package com.sm.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sm.tool.entity.po.Tickets_;
import com.sm.tool.entity.po.UserTicket;
import com.sm.tool.entity.po.User_;
import com.sm.tool.entity.request.PageInfo;
import com.sm.tool.entity.response.ReturnData;
import com.sm.tool.entity.vo.UserDetailListVO;
import com.sm.tool.entity.vo.UserDetailVO;
import com.sm.tool.entity.vo.UserTicketsVO;
import com.sm.tool.enums.NumberEnums;
import com.sm.tool.enums.ResultEnums;
import com.sm.user.feigns.TicketFeignClient;
import com.sm.user.mapper.UserRegLoginMapper;
import com.sm.user.mapper.UserTicketMapper;
import com.sm.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.JedisCluster;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private JedisCluster jedisCluster;
    @Autowired
    private UserRegLoginMapper userRegLoginDao;

    @Autowired
    private UserTicketMapper userTicketMapper;

    @Autowired
    private TicketFeignClient ticketFeignClient;


    @Override
    public ReturnData<UserDetailVO> getUserInfo(String token) {

        QueryWrapper<User_> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq("id", jedisCluster.get(token));
        User_ user = userRegLoginDao.selectOne(queryWrapper);

        UserDetailVO userDetailVO = new UserDetailVO();
        BeanUtils.copyProperties(user, userDetailVO);

        return ReturnData.<UserDetailVO>builder().Data(userDetailVO).code(ResultEnums.SUCCESS.getCode()).msg(ResultEnums.SUCCESS.getMessage()).build();
    }


    @Override
    public ReturnData<UserDetailListVO> getUserList(PageInfo pageInfo) {
        UserDetailListVO userDetailListVO = new UserDetailListVO();

        Page page = new Page(pageInfo.getCurrent(), pageInfo.getSize());
        IPage<User_> userIPage = userRegLoginDao.selectUserList(page);
        List<User_> userList = userIPage.getRecords();
        userDetailListVO.setCurrent(pageInfo.getCurrent());
        userDetailListVO.setTotal(userIPage.getTotal());

        List<UserDetailVO> userDetailVOList = new ArrayList<>();

        for (User_ user_ : userList) {
            UserDetailVO userDetailVO = new UserDetailVO();
            BeanUtils.copyProperties(user_, userDetailVO);
            userDetailVOList.add(userDetailVO);
        }
        userDetailListVO.setUserDetailVOList(userDetailVOList);

        return ReturnData.<UserDetailListVO>builder()
                .Data(userDetailListVO)
                .code(ResultEnums.SUCCESS.getCode())
                .msg(ResultEnums.SUCCESS.getMessage())
                .build();
    }

    /**
     * 模拟用户充值
     *
     * @param token
     * @return
     */
    @Override
    public ReturnData userRecharge(String token) {
        String userId = jedisCluster.get(token);

        UpdateWrapper<User_> user_updateWrapper = new UpdateWrapper<>();
        user_updateWrapper.eq("id", Long.parseLong(userId));
        userRegLoginDao.update(User_.builder().balance(new BigDecimal(10000)).build(), user_updateWrapper);
        return ReturnData.builder().Data("充值成功,当前账户余额已重置为1万元").build();
    }

    /**
     * 查询用户优惠卷
     * 检查到过期优惠卷，便update优惠卷状态
     *
     * @param token
     * @return
     */
    @Override
    public ReturnData<List<UserTicketsVO>> queryUserTickets(String token) {
        List<UserTicketsVO> userTicketsVOList = new ArrayList<>();

        String userId = jedisCluster.get(token);
        QueryWrapper<UserTicket> userTicketQueryWrapper = new QueryWrapper<>();
        userTicketQueryWrapper.eq("user_id", Long.parseLong(userId));
        List<UserTicket> userTicketList = userTicketMapper.selectList(userTicketQueryWrapper);

        /**
         * 已过期的优惠卷Id集合
         */
        List<Long> expriceTicketIds = new ArrayList<>();

        List<Long> ticketIds = new ArrayList<>();
        for (UserTicket userTicket : userTicketList) {
            ticketIds.add(userTicket.getTicketId());
            /**
             * 检查该卷是否已过期
             * if is exprice yes update
             */
            if (checkTicketIsExprice(userTicket.getExpriceTime())) {
                expriceTicketIds.add(userTicket.getTicketId());
            }
        }
        if (!expriceTicketIds.isEmpty()) {
            //更新sm-ticket库中卷状态
            UpdateWrapper<UserTicket> userTicketUpdateWrapper = new UpdateWrapper<>();
            userTicketUpdateWrapper.eq("id", expriceTicketIds);
            int updateExpriceCount = userTicketMapper.update(UserTicket.builder().status(NumberEnums.ONE.getNumber()).build(), userTicketUpdateWrapper);
            log.info("失效券更新成功，数目:{}.触发条件 用户自主查看...", updateExpriceCount);
        }


        Long[] ticketIdsArray = new Long[ticketIds.size()];
        ticketIds.toArray(ticketIdsArray);

        List<Tickets_> ticketsList = ticketFeignClient.queryTicketListByIds(ticketIdsArray);

        for (UserTicket userTicket : userTicketList) {
            for (Tickets_ ticket : ticketsList) {
                if (userTicket.getTicketId().equals(ticket.getId())) {
                    UserTicketsVO userTicketsVO = UserTicketsVO.builder().build();
                    userTicketsVO.setTicketName(ticket.getTicketName());
                    userTicketsVO.setDiscount(ticket.getDiscount());
                    userTicketsVO.setExplains(ticket.getExplains());
                    userTicketsVO.setFullRed(ticket.getFullRed());
                    userTicketsVO.setTermOfValidity(ticket.getTermOfValidity());
                    userTicketsVO.setType(ticket.getType());
                    userTicketsVO.setVerticalReduction(ticket.getVerticalReduction());
                    userTicketsVO.setTicketCode(ticket.getTicketCode());
                    userTicketsVO.setStatus(userTicket.getStatus());
                    userTicketsVOList.add(userTicketsVO);
                }
            }
        }

        return ReturnData.<List<UserTicketsVO>>builder().Data(userTicketsVOList).build();
    }

    boolean checkTicketIsExprice(Date expriceTimeDate) {
        return System.currentTimeMillis() > expriceTimeDate.getTime();
    }
}
